package org.dromara.crawler.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mongodb.client.gridfs.model.GridFSFile;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.bson.types.ObjectId;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.crawler.domain.vo.ElementTargetVo;
import org.dromara.crawler.domain.vo.HotspotEventVo;
import org.dromara.crawler.mongo.mongodomain.HotspotEvent;
import org.dromara.crawler.mongo.mongoservice.HotspotEventService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLConnection;
import java.util.List;

import static cn.dev33.satoken.SaManager.log;

/**
 * 热点管理接口
 */
@RestController
@RequestMapping("/hotspotEvent")
public class HotspotEventController {

    @Autowired
    private HotspotEventService hotspotEventService;

    private GridFsTemplate hotpotGridFsTemplate;

    public HotspotEventController(@Qualifier("hotpotGridFsTemplate") GridFsTemplate hotpotGridFsTemplate) {
        this.hotpotGridFsTemplate = hotpotGridFsTemplate;
    }

    /**
     * 查询所有热点事件
     */
    @GetMapping("/getAll")
    public R<List<HotspotEvent>> getAll() {
        try {
            return R.ok(hotspotEventService.getAll());
        } catch (Exception e) {
            log.error("获取所有热点事件失败，原因：" + e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 根据id查询
     */
    @GetMapping("/getById")
    public R<HotspotEvent> getById(@RequestParam String id) {
        try {
            return R.ok(hotspotEventService.queryById(id));
        } catch (Exception e) {
            log.error("根据id查询热点事件失败，原因：" + e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 查询所有热点事件，按分数和时间排序，支持关键词搜索
     */
    @GetMapping("/getAllOrderByScoreAndTime")
    public R<List<HotspotEvent>> getAllOrderByScoreAndTime(@RequestParam(required = false) String searchKeywords) {
        try {
            return R.ok(hotspotEventService.getAllOrderByScoreAndTime(searchKeywords));
        } catch (Exception e) {
            log.error("获取热点事件失败，原因：" + e.getMessage());
            return R.fail(e.getMessage());
        }
    }
    /**
     * 根据事件ID查询热点事件树形结构
     */
    @GetMapping("/getTreeByEventId")
    public R<Object> getTreeByEventId(@RequestParam(required = false) String eventId) {
        try {
            return R.ok(hotspotEventService.queryHotspotEventTree(eventId));
        } catch (Exception e) {
            log.error("根据事件ID查询热点事件树形结构失败，原因：" + e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 事件按月分组统计
     */
    @GetMapping("/getMonthStatistics")
    public R<Object> getMonthStatistics(@RequestParam(required = false) String keyword) {
        return R.ok(hotspotEventService.getMonthStatistics(keyword));
    }
    /**
     * 分页查询热点事件
     */
    @GetMapping("/queryHotspotEventPage")
    public R<Page<HotspotEvent>> queryHotspotEventPage(@RequestParam(required = false) String keyword, PageQuery pageQuery) {
        return R.ok(hotspotEventService.queryHotspotEventPage(keyword, pageQuery));
    }

    /**
     * 获取热点事件及相关的事件清单
     * @return
     */
    @GetMapping("/getHotspotEvent")
    public R<List<HotspotEventVo>> getHotspotEvent(){
        return R.ok(hotspotEventService.getHotspotEvent());
    }

    /**
     * 获取热点事件相关的目标列表
     * @return
     */
    @GetMapping("/getRelatedTargets")
    public R<List<ElementTargetVo>> getRelatedTargets(@RequestParam String hotspotEventId){
        return R.ok(hotspotEventService.getRelatedTargets(hotspotEventId));
    }

    /**
     * 查询热点事件相关的图片接口
     */
    @GetMapping("/getHotpotImage")
    public void getHotpotImage(@RequestParam String imageId, HttpServletResponse response) {
        getOutputStream(imageId, response, hotpotGridFsTemplate);
    }

    private void getOutputStream(String imageId, HttpServletResponse response, GridFsTemplate gridFsTemplate) {
        try {
            // 查询 GridFS 文件
            GridFSFile file = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(new ObjectId(imageId))));
            if (file == null) {
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                response.setContentType("text/plain");
                response.getWriter().write("Image not found.");
                return;
            }
            // 获取文件资源
            GridFsResource resource = gridFsTemplate.getResource(file);
            // 尝试从 metadata 获取 contentType，否则根据文件名后缀推断
            String contentType = null;
            if (file.getMetadata() != null && file.getMetadata().get("_contentType") != null) {
                contentType = file.getMetadata().get("_contentType").toString();
            } else {
                contentType = URLConnection.guessContentTypeFromName(resource.getFilename());
            }
            if (contentType == null) {
                contentType = "application/octet-stream"; // fallback
            }

            // 设置响应头
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", "inline; filename=\"" + resource.getFilename() + "\"");
            // 输出图片内容
            try (InputStream is = resource.getInputStream(); OutputStream os = response.getOutputStream()) {
                StreamUtils.copy(is, os); // 更简洁
            }
        } catch (Exception e) {
            // 统一错误处理（返回状态码 + 消息）
            try {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.setContentType("text/plain");
                response.getWriter().write("读取图片异常：" + e.getMessage());
                e.printStackTrace();
            } catch (IOException ioException) {
                // 忽略
            }
        }
    }

}
